package ch.common.action.umTableActioin;

import ch.common.util.genericsUtil.GenericsUtils;
import ch.common.util.jsonValueProcessor.JsonDateTimeValueProcessor;
import ch.common.util.page.PageModel;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;

import ch.common.dao.BaseDao;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired;

import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.PropertyFilter;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
/**
 * Action类的基类。
 * @author grc
 * @date 2015-10-9 13:51:38
 */
@SuppressWarnings({ "serial" })
public abstract class BaseAction< T , T_DAO extends BaseDao<T> >  extends ActionSupport implements ModelDriven<T>{
	


	public static final String Query 		= "Query";
	public static final String Delete 		= "Delete";
	public static final String PrintData 	= "PrintData";
	/**
	 * saveOrUpdate
	 */
	public static final String Submit		= "Submit";
	public static final String Save			= "Save";
	public static final String Update		= "Update";
	
	/**
	 * 查询方法
	 * @return Query
	 */
	public String Query(){
		
		doSetWhere();
		doSetT_DAO();
		doQuery();
		doChangePageModelToJsonString();
		
		return Query;
	}
	/**
	 * 删除方法
	 * @return Delete
	 */
	public String Delete(){
		
		System.out.println(GenericsUtils.getGenericName(entityClass)+" "+Delete);


		doDeleteSetTEntity();
		doSetT_DAO();
		doDelete();
		
		return Delete;
	}
	/**
	 * 保存方法(saveOrUpdate) <br/>
	 * <b>添加一条记录或者修改一条记录</b>
	 * @return Submit
	 */
	public String Submit(){

		System.out.println(GenericsUtils.getGenericName(entityClass)+" "+Submit);
		
		doSubmitSetTEntity();
		doSetT_DAO();
		doSaveOrUpdateEntity();
		
		return Submit;
	}	
	/**
	 * 保存方法(save) <br>
	 * <b>实际上就是添加一条记录</b>
	 * @return Save
	 */
	public String Save(){
		System.out.println(GenericsUtils.getGenericName(entityClass)+" "+Save);
		
		doSaveSetTEntity();
		doSetT_DAO();
		doSaveEntity();
		return Save;
	}
	/**
	 * 保存方法(Update)<br/>
	 * <b>原来基础上修改一条记录</b>
	 * @return Update
	 */
	public String Update(){
		System.out.println(GenericsUtils.getGenericName(entityClass)+" "+Update);
		
		doUpdateSetTEntity();
		doSetT_DAO();
		doUpdateEntity();
		
		return Update;
	}
	/**
	 * 显示一行记录的方法
	 * @return PrintData
	 */
	public String PrintData(){

		System.out.println(GenericsUtils.getGenericName(entityClass)+" "+PrintData);

		doGetTEntity();
		doSetT_DAO();
		doChangeTEntityToJsonString();
		
		return PrintData;
	}
	
	
	public void doDelete(){
		t_DAO.delete(t);
	}
	/**
	 * 这个方法是 <b>虚方法</b>， 子类必须实现。<br/>
	 * 获得T为适应子类的Entity类 <br/>
	 */
	public abstract void doGetTEntity();
	/**
	 * 这个方法是 <b>虚方法</b>， 子类必须实现。<br/>
	 * 设置T为适应子类的Entity类 <br/>
	 * 对应delete方法
	 */
	public abstract void doDeleteSetTEntity();
	/**
	 * 这个方法是 <b>虚方法</b>， 子类必须实现。<br/>
	 * 设置T为适应子类的Entity类 <br/>
	 * 对应submit方法
	 */
	public abstract void doSubmitSetTEntity();
	/**
	 * 这个方法是 <b>虚方法</b>， 子类必须实现。<br/>
	 * 设置T为适应子类的Entity类 <br/>
	 * 对应Save方法
	 */
	public abstract void doSaveSetTEntity();
	/**
	 * 这个方法是 <b>虚方法</b>， 子类必须实现。<br/>
	 * 设置T为适应子类的Entity类 <br/>
	 * 对应Update方法
	 */
	public abstract void doUpdateSetTEntity();
	
	/**
	 * 保存或更新实体到数据库.
	 */
	public void doSaveOrUpdateEntity(){
//		t_DAO.saveOrUpdate(t);
	}
	/**
	 * 保存实体到数据库.
	 */
	public void doSaveEntity(){
		t_DAO.save(t);
	}
	/**
	 * 更新实体到数据库.
	 */
	public void doUpdateEntity(){
		t_DAO.update(t);
	}
	/**
	 * 设置实施查询时hql语句的 where字段.
	 */
	protected void doSetWhere(){
		this.setWhere("");
	}
	
	/**
	 * 子类选择实现。<br/>
	 * 设置T_DAO为适应子类的dao类 <br/>
	 */
	@SuppressWarnings("unchecked")
	protected  void doSetT_DAO(){
//		t_DAO = (T_DAO) DaoFactory.createDao(GenericsUtils.getGenericName(entityClass));
	};
	
	/**
	 * 实施查询
	 */
	protected void doQuery(){
		
//		pageModel =	t_DAO.find(where, null, null, Integer.parseInt(pageNumber==null?"1":pageNumber), pageSize);
	}
	
	/**
	 * 将 分页工具类pageModel 转成json字符串 并返回。
	 */
	protected void doChangePageModelToJsonString(){

		JSONObject msg = null;

		setJsonConfig();
		
		msg = JSONObject.fromObject(pageModel,jsonConfig);//java对象转化为JSON对象
		
		System.out.println(msg.toString());
		
		printWriterToWrite(msg.toString());//http请求返回JSON字符串
	}
	
	/**
	 * 将 泛型类t 转成json字符串 并返回。
	 */
	protected void doChangeTEntityToJsonString(){

		JSONObject msg = null;
		
		setJsonConfig();
		
		msg = JSONObject.fromObject(t,jsonConfig);//java对象转化为JSON对象
		
		System.out.println(msg.toString());
		
		printWriterToWrite(msg.toString());//http请求返回JSON字符串
	}
	
	/**
	 * 设置JsonConfig
	 * 2015-12-4 14:35:36
	 */
	protected void setJsonConfig(){
		/*
		 * 将时间类型都转成'YYYY-MM-DD hh:mm:ss'格式字符串。
		 */
		jsonConfig.registerJsonValueProcessor(java.util.Date.class, new JsonDateTimeValueProcessor());

		/*
		 * 过滤掉不想转换的属性。
		 * 一般需要子类重载。
		 */
//		public boolean apply(Object source/* 属性的拥有者 */ , String name /*属性名字*/ , Object value/* 属性值 */ ){  
//		jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
//			@Override
//			public boolean apply(Object arg0, String arg1, Object arg2) {
//				if (arg1.equals("pmManufacturingOrder")) {
//					return true;
//				} else {
//					return false;
//				}
//			}
//		});
	}
	
	/**
	 * 改变输出流的内容 <br/>
	 * 改变内容为 msg <br/>
	 * 输出流格式为utf-8<br/>
	 */
	protected void printWriterToWrite(String msg){
		
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out;
		try {
			out = response.getWriter();
			out.print(msg);
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	


	/**
	 * javaBean转json 的转换配置类。
	 */
	protected JsonConfig jsonConfig = new JsonConfig();
	
	protected int pageNo = 1;
	/**
	 * 一页共多少行  <br/>
	 * 默认为5 <br/>
	 */
	protected int pageSize = 5;

	/**
	 * 第几页
	 */
	protected String pageNumber;
	
	/**
	 * T泛型类
	 */
	protected T t ;

	/**
	 * DAO的泛型类
	 */
	protected T_DAO t_DAO;
	
	/**
	 * 实施查询时hql语句的 where字段。
	 */
	protected String where = "";
	
	/**
	 * 分页工具类
	 */
	protected PageModel<T> pageModel;
	
	@SuppressWarnings("unchecked")
	protected  Class<T> entityClass = GenericsUtils.getGenericType(this.getClass());
	
	/**
	 * 内部类PairStr
	 * @author grc
	 * @date 2015-11-15 19:49:14
	 */
	protected class PairStr{
		private String str1;
		private String str2;
		
		public String getStr1() {
			return str1;
		}

		public void setStr1(String str1) {
			this.str1 = str1;
		}

		public String getStr2() {
			return str2;
		}

		public void setStr2(String str2) {
			this.str2 = str2;
		}

		public PairStr(){}
		
		public PairStr(String str1,String str2){
			setStr1(str1);
			setStr2(str2);
		}
	}
	
	public int getPageNo() {
		return pageNo;
	}
	public int getPageSize() {
		return pageSize;
	}
	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	
	public String getPageNumber() {
		return pageNumber;
	}


	public void setPageNumber(String pageNumber) {
		this.pageNumber = pageNumber;
	}

	public T getT() {
		return t;
	}
	public void setT(T t) {
		this.t = t;
	}

	public String getWhere() {
		return where;
	}
	public PageModel<T> getPageModel() {
		return pageModel;
	}
	public void setWhere(String where) {
		this.where = where;
	}
	public void setPageModel(PageModel<T> pageModel) {
		this.pageModel = pageModel;
	}
	public T_DAO getT_DAO() {
		return t_DAO;
	}

	public void setT_DAO(T_DAO t_DAO) {
		this.t_DAO = t_DAO;
	}
}
